#region COPYRIGHT
//--------------------------------------------------------------------------------
// <copyright file="Cache.cs" company="starLiGHT Entertainment Studios">
//    Copyright (c) 2007, 2008, 2009, 2010, 2011
//       Roland Rosenkranz (Glatzemann@email.de)
//
//    Based on libnoise by Jason Bevins
//      Copyright (C) 2003, 2004 Jason Bevins (licensed under LGPL)
// </copyright>
// <license>
//   This file is part of starLiGHT.Noise.
//
//   starLiGHT.Noise is free software: you can redistribute it and/or modify
//   it under the terms of the GNU Lesser General Public License as published by
//   the Free Software Foundation, either version 3 of the License, or
//   (at your option) any later version.
//
//   starLiGHT.Noise is distributed in the hope that it will be useful,
//   but WITHOUT ANY WARRANTY; without even the implied warranty of
//   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//   GNU Lesser General Public License for more details.
//
//   You should have received a copy of the GNU Lesser General Public License
//   along with starLiGHT.Noise. If not, see http://www.gnu.org/licenses/.
//    
//   ADDITIONAL (commercial) LICENSES for starLiGHT.Noise are available on request.
// </license>
// <version>
// **************[ starLiGHT.Engine SVN ]**********************
// * $Rev:: 10385                 $:  Revision of last commit *
// * $Author:: unknown            $:  Author of last commit   *
// * $Date:: 2011-06-14 07:59:17 #$:  Date of last commit     *
// ************************************************************
// </version>
//--------------------------------------------------------------------------------
#endregion

namespace starLiGHT.Noise.Noise
{
    #region Using Statements
    using System;
    using System.Collections.Generic;
    using System.Text;

    #endregion

    /// Noise module that caches the last output value generated by a source
    /// module.
    ///
    /// If an application passes an input value to the GetValue() method that
    /// differs from the previously passed-in input value, this noise module
    /// instructs the source module to calculate the output value.  This
    /// value, as well as the (@a x, @a y, @a z) coordinates of the input
    /// value, are stored (cached) in this noise module.
    ///
    /// If the application passes an input value to the GetValue() method
    /// that is equal to the previously passed-in input value, this noise
    /// module returns the cached output value without having the source
    /// module recalculate the output value.
    ///
    /// If an application passes a new source module to the SetSourceModule()
    /// method, the cache is invalidated.
    ///
    /// Caching a noise module is useful if it is used as a source module for
    /// multiple noise modules.  If a source module is not cached, the source
    /// module will redundantly calculate the same output value once for each
    /// noise module in which it is included.
    ///
    /// This noise module requires one source module.
    public class Cache : Module
    {
        /// The cached output value at the cached input value.
        protected double cachedValue;

        /// Determines if a cached output value is stored in this noise
        /// module.
        protected bool isCached;

        /// @a x coordinate of the cached input value.
        protected double cacheX;

        /// @a y coordinate of the cached input value.
        protected double cacheY;

        /// @a z coordinate of the cached input value.
        protected double cacheZ;

        /// Constructor.
        public Cache() : base(1)
        {
            this.isCached = false;
        }

        public override double GetValue(double x, double y, double z, double lowerXBound, double upperXBound, double lowerZBound, double upperZBound)
        {
            System.Diagnostics.Debug.Assert(sourceModule[0] != null, String.Empty);

            if (!(this.isCached && x == this.cacheX && y == this.cacheY && z == this.cacheZ))
            {
                this.cachedValue = sourceModule[0].GetValue(x, y, z, lowerXBound, upperXBound, lowerZBound, upperZBound);
                this.cacheX = x;
                this.cacheY = y;
                this.cacheZ = z;
            }
            this.isCached = true;
            return this.cachedValue;
        }

        public override void SetSourceModule(int index, Module sourceModule)
        {
            this.SetSourceModule(index, sourceModule);
            this.isCached = false;
        }
    }
}

